Strip basedirs from the compiler arguments too - #2840
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2840 +/- ##
==========================================
+ Coverage 76.22% 76.30% +0.07%
==========================================
Files 72 72
Lines 39890 40027 +137
==========================================
+ Hits 30407 30541 +134
- Misses 9483 9486 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hi @avikivity , Thanks for your PR. Please, fix the CI build |
53813b1 to
6aeafcf
Compare
|
Update: apply cargo fmt |
6aeafcf to
35175d2
Compare
|
Update: increase test coverage |
| Cow::Owned(result) | ||
| } | ||
|
|
||
| /// Strip the base directories from a single compiler argument, for hashing. |
There was a problem hiding this comment.
do we really need such a long comment?
There was a problem hiding this comment.
It is rather long, but I think the details are not obvious here.
It's easy to skip over an overlong comment, but not easy to reverse-engineer the details when the comment isn't there.
|
please add an integration test / end-to-end that should that it is fixed. |
35175d2 to
24b073f
Compare
Done. |
|
Waiting for #2853 |
24b073f to
24ca766
Compare
SCCACHE_BASEDIRS strips the base directories from the preprocessed source, but the compiler arguments are hashed verbatim. That leaves out the one thing that most reliably ties a cache entry to a single checkout: a flag that names the tree it is building. -ffile-prefix-map=/home/user/project=. The flag exists precisely so the object file does not depend on where the tree lives - every path it records is rewritten to `.` - so two checkouts of the same commit produce identical objects. They just never agree on the hash, because the flag itself spells the path out, and so they never share an entry. Which is the case basedirs is for. Strip basedirs from each argument before hashing it, at the places where an argument is expected to spell a pathname, and only there: the whole argument, as in a source file or the path of a separated option; the value of an option written with an `=`, which covers either half of a prefix map; and the value glued to a short option such as -I. A basedir appearing anywhere else is left alone, so -DROOT="/home/user/project", which the compiler bakes into the output verbatim, still counts towards the hash. Basedirs carry a trailing slash so that they only match whole path components; in an argument a component can also end at the `=` of a prefix map, or at the end of the argument, so accept those two as well. A sibling /home/user/project-docs is still not a match. The longest basedir wins. Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the arguments now reach the hash as bytes rather than through OsString's Hash impl. An integration test is added to tests/integration.
24ca766 to
c7c9894
Compare
|
Update: added missing file-prefix-map integration test script |
|
looks good, thanks for the test |
SCCACHE_BASEDIRS strips the base directories from the preprocessed source, but the compiler arguments are hashed verbatim. That leaves out the one thing that most reliably ties a cache entry to a single checkout: a flag that names the tree it is building.
-ffile-prefix-map=/home/user/project=.
The flag exists precisely so the object file does not depend on where the tree lives - every path it records is rewritten to
.- so two checkouts of the same commit produce identical objects. They just never agree on the hash, because the flag itself spells the path out, and so they never share an entry. Which is the case basedirs is for.Strip basedirs from each argument before hashing it, at the places where an argument is expected to spell a pathname, and only there: the whole argument, as in a source file or the path of a separated option; the value of an option written with an
=, which covers either half of a prefix map; and the value glued to a short option such as -I. A basedir appearing anywhere else is left alone, so -DROOT="/home/user/project", which the compiler bakes into the output verbatim, still counts towards the hash.Basedirs carry a trailing slash so that they only match whole path components; in an argument a component can also end at the
=of a prefix map, or at the end of the argument, so accept those two as well. A sibling /home/user/project-docs is still not a match. The longest basedir wins.Bump CACHE_VERSION and the preprocessor cache's FORMAT_VERSION, since the arguments now reach the hash as bytes rather than through OsString's Hash impl.